<template>
  <div class="middle-header">
    <div class="cancel-and-recovery">
      <el-link :underline="false" type="danger" @click="cancel">撤销</el-link>
      <el-link :underline="false" type="primary" @click="recovery"
        >恢复</el-link
      >
    </div>
    <div></div>
    <div class="action-group">
      <el-link :underline="false" type="primary" @click="clearTemplate"
        >清空</el-link
      >
      <el-link :underline="false" type="primary" @click="importTemplate"
        >导入</el-link
      >
      <el-link :underline="false" type="primary" @click="exportTemplate"
        >导出</el-link
      >
      <el-link :underline="false" type="primary" @click="previewTemplate"
        >预览</el-link
      >
      <el-link :underline="false" type="primary" @click="saveTemplate"
        >保存</el-link
      >
    </div>

    <!-- 导入模板 -->
    <el-dialog
      v-model="importVisible"
      fullscreen
      append-to-body
      destroy-on-close
      title="导入模板"
    >
      <low-code-editor
        ref="importEditorRef"
        :mode="'json'"
        :readonly="false"
        v-model="editorCode"
      ></low-code-editor>

      <div class="footer">
        <el-button type="primary" @click="importSave">导入</el-button>
      </div>
    </el-dialog>

    <!-- 导出模板 -->
    <el-dialog
      v-model="exportVisible"
      fullscreen
      append-to-body
      destroy-on-close
      title="导出模板"
    >
      <low-code-editor
        ref="exportEditorRef"
        :mode="'json'"
        :readonly="true"
        v-model="editorCode"
      ></low-code-editor>
    </el-dialog>

    <!-- 预览模板 -->
    <el-dialog
      v-model="previewVisible"
      width="70%"
      append-to-body
      :close-on-click-modal="false"
      destroy-on-close
      title="预览"
    >
      <page-render
        v-if="previewVisible"
        :pageJson="pageJson"
        ref="pageRenderRef"
      ></page-render>
      <div class="footer" style="text-align: right; padding-top: 20px">
        <el-button type="default" @click="getModelData">获取数据</el-button>
      </div>
    </el-dialog>

    <el-dialog
      v-model="dataModelVisible"
      append-to-body
      destroy-on-close
      title="数据模型"
    >
      <low-code-editor
        v-if="dataModelVisible"
        ref="dataModelEditorRef"
        :mode="'json'"
        :readonly="true"
        v-model="dataModelCode"
      ></low-code-editor>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  onMounted,
  onBeforeUnmount,
  nextTick,
  inject,
} from "vue";
import { LowCodeImp } from "@/components/low-code/core/index";
import { ElMessage } from "element-plus";
import { tools } from "@/components/low-code/page-designer/utils";
import clone from "clone";
import pageRender from "@/components/low-code/page-render/render/index.vue";
import { LowCodeType } from "@/components/low-code/core/type";

export default defineComponent({
  components: { pageRender },
  setup() {
    const getLowCodeInstance = inject("getLowCodeInstance") as Function;
    const lowCode = getLowCodeInstance() as LowCodeImp;

    const updateLowCode = (arg?: LowCodeType): void => {
      const defaultMeta = {
        key: "",
        currentKey: "",
        root: {
          items: [],
        },
        model: {},
        dataCenter: {},
        eventCollection: [],
        dataSource: [],
      };
      Object.assign(lowCode, defaultMeta, arg);
      lowCode.init();
    };

    const editorCode = ref("{}");
    onMounted(() => {
      window.addEventListener("resize", initHeight);
    });
    const pageRenderRef = ref();
    const getModelData = () => {
      console.log(lowCode.model);

      const rawModel = pageRenderRef.value.lowCodeRender.model;

      // 过滤掉值为 null/undefined/''/空的数组或对象
      const filteredModel = Object.entries(rawModel).reduce(
        (acc, [key, value]) => {
          if (
            value !== null &&
            value !== undefined &&
            value !== "" &&
            !(Array.isArray(value) && value.length === 0) &&
            !(typeof value === "object" && Object.keys(value).length === 0)
          ) {
            acc[key] = value;
          }
          return acc;
        },
        {} as any
      );

      dataModelCode.value = JSON.stringify(filteredModel, null, 2);
      dataModelVisible.value = true;
    };

    onBeforeUnmount(() => {
      window.removeEventListener("resize", initHeight);
    });
    const height = ref(0);
    const initHeight = () => {
      height.value = document.documentElement.clientHeight - 120;
    };
    initHeight();

    const dataModelCode = ref("{}");

    const importEditorRef = ref();
    const importVisible = ref(false);
    const exportEditorRef = ref();
    const exportVisible = ref(false);
    const dataModelVisible = ref(false);
    const clearTemplate = () => {
      updateLowCode();
    };
    const importTemplate = () => {
      editorCode.value = "";
      importVisible.value = true;
      nextTick(() => {
        importEditorRef.value.setValue("");
      });
    };
    const importSave = () => {
      try {
        let templateJson = JSON.parse(editorCode.value);
        updateLowCode(templateJson);
        ElMessage.success("导入成功");
        importVisible.value = false;
        editorCode.value = "";
      } catch (error) {
        ElMessage.error("解析失败");
      }
    };

    const exportTemplate = () => {
      exportVisible.value = true;
      const template = {
        root: lowCode.root,
        model: lowCode.model,
        eventCollection: lowCode.eventCollection,
        dataSource: lowCode.dataSource,
        globalConfig: lowCode.globalConfig,
      };
      setTimeout(() => {
        exportEditorRef.value.setValue(JSON.stringify(template, null, 2));
      });
    };

    const pageJson = ref({});
    const previewVisible = ref(false);
    const previewTemplate = () => {
      previewVisible.value = true;
      pageJson.value = JSON.parse(JSON.stringify(lowCode));
    };

    const saveTemplate = () => {
      ElMessage.info("待开发");
    };

    const cancel = () => {
      if (tools.handleStack.size() <= 0) {
        return false;
      }
      if (tools.handleStack.getLastOperation() == "push") {
        let lowcode = tools.handleStack.pop();
        tools.restoreHandleStack.push(clone(lowcode));
      }
      let lowcode = tools.handleStack.pop();
      tools.restoreHandleStack.push(clone(lowcode));
      console.log(lowcode);
      updateLowCode(lowcode);
    };

    const recovery = () => {
      if (tools.restoreHandleStack.size() <= 0) {
        return false;
      }
      if (tools.restoreHandleStack.getLastOperation() == "push") {
        let lowcode = tools.restoreHandleStack.pop();
        tools.handleStack.push(clone(lowcode));
      }
      let lowcode = tools.restoreHandleStack.pop();
      tools.handleStack.push(clone(lowcode));
      console.log(lowcode);
      updateLowCode(lowcode);
    };

    return {
      editorCode,
      height,
      initHeight,
      importEditorRef,
      importVisible,
      exportEditorRef,
      exportVisible,
      previewVisible,
      dataModelVisible,
      dataModelCode,
      clearTemplate,
      importTemplate,
      importSave,
      exportTemplate,
      previewTemplate,
      saveTemplate,
      cancel,
      recovery,
      pageJson,
      getModelData,
      pageRenderRef,
    };
  },
});
</script>

<style scoped>
.middle-header {
  position: absolute;
  width: 100%;
  height: 45px;
  line-height: 45px;
  border-bottom: 1px dashed #e0e0e0;
  background: white;
  z-index: 200;
  display: flex;
  justify-content: space-between;
  padding: 0 10px;
}

.cancel-and-recovery > a {
  padding: 0 8px;
}
.action-group > a {
  padding: 0 8px;
}
</style>
